package com.ys.service.hr.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;

import com.ys.entity.hr.ThrVatApplyDetailCbb;
import com.ys.entity.storage.TccLogisticsSadFile;
import com.ys.mapper.hr.ThrVatApplyDetailCbbMapper;
import com.ys.mapper.storage.TccLogisticsSadFileMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ys.dto.AddDto;
import com.ys.dto.EditDto;
import com.ys.entity.flow.YspModel;
import com.ys.entity.hr.ThrVatApply;
import com.ys.entity.hr.ThrVatApplyDetail;
import com.ys.entity.sys.TsUserChange;
import com.ys.entity.sys.YsMenu;
import com.ys.entity.sys.YsProcInst;
import com.ys.enume.flow.FlowEnum;
import com.ys.enume.flow.YsProcInstEnum;
import com.ys.enume.hr.ThrVatApplyDetailEnum;
import com.ys.enume.hr.ThrVatApplyEnum;
import com.ys.mapper.hr.HrMapper;
import com.ys.mapper.hr.ThrVatApplyDetailMapper;
import com.ys.mapper.hr.ThrVatApplyMapper;
import com.ys.service.flow.YspTaskService;
import com.ys.service.hr.ThrVatApplyService;
import com.ys.util.shiro.ShiroUtils;
import com.ys.vo.Flow;
import com.ys.vo.R;

@Service("thrVatApplyService")
public class ThrVatApplyServiceImpl implements ThrVatApplyService {

	@Autowired
	private HrMapper hrMapper;
	@Autowired
	private ThrVatApplyMapper thrVatApplyMapper;
	@Autowired
	private ThrVatApplyDetailMapper thrVatApplyDetailMapper;

	@Autowired
	private YspTaskService yspTaskService;

	@Autowired
	private ThrVatApplyDetailCbbMapper thrVatApplyDetailCbbMapper;

	@Autowired
	private TccLogisticsSadFileMapper tccLogisticsSadFileMapper;
	/**
	 * 新增
	 * @param params
	 * @return
	 * @throws Exception
	 */
	@Override
	public R add(String bid, String detailArr, Long menuId) throws Exception {

		if (bid == null || bid.length() == 0) {
			return R.error("单号不能为空");
		} else if(new ThrVatApply().setBid(bid).count() > 0) {
			return R.error("单号已存在");
		}
		
		/*
		 *  验证详情数据物料
		 *  1、VAT号不能为空
		 *  2、类型不能为空，类型为公司管理时，税额不能为空
		 *  3、申报周期不能为空
		 */
		JSONArray detailJA = JSON.parseArray(detailArr);
		if (detailJA == null || detailJA.size() == 0) {
			return R.error("详情数据不能为空");
		}
		for (int i = 0; i < detailJA.size(); i++) {
			JSONObject detailJO = detailJA.getJSONObject(i);
			String vatNo = detailJO.getString("vatNo");
			if (vatNo == null || vatNo.length() == 0) {
				return R.error("VAT号不能为空");
			}
			String currentDateBegin = detailJO.getString("currentDateBegin");
			if (currentDateBegin == null || currentDateBegin.length() == 0) {
				return R.error("申报周期(起始)不能为空");
			}
			String currentDateEnd = detailJO.getString("currentDateEnd");
			if (currentDateEnd == null || currentDateEnd.length() == 0) {
				return R.error("申报周期(截止)不能为空");
			}
			String vatPaymentAccountCode = detailJO.getString("vatPaymentAccountCode");
			if (vatPaymentAccountCode == null || vatPaymentAccountCode.length() == 0) {
				return R.error("VAT付款账户编码不能为空");
			}
			
			Integer type = detailJO.getInteger("type");
			if (type == null) {
				return R.error("类型不能为空");
			}
			if (type == ThrVatApplyDetailEnum.Type.COMPANY.value) {
				BigDecimal taxAmount = detailJO.getBigDecimal("taxAmount");
				if (taxAmount == null) {
					return R.error("税额不能为空");
				} else if (taxAmount.compareTo(BigDecimal.ZERO) < 0) {
					return R.error("税额必须为正");
				}
			}
		}
		
		String loginUserId = ShiroUtils.getUserId();
		TsUserChange tsUserChange = new TsUserChange().setUserId(loginUserId).setStatus(1).queryFirst();
		
		ThrVatApply entity = null;
		{
			Integer effectStock = FlowEnum.EffectStock.NOT_EFFECT.value;
			Long createChangeId = tsUserChange.getId();
			entity = ThrVatApply.thrVatApply(bid, effectStock, createChangeId, 1);
			thrVatApplyMapper.insert(entity);
		}
		
		// 添加VAT申报明细
		for (int i = 0; i < detailJA.size(); i++) {
			JSONObject detailJO = detailJA.getJSONObject(i);
			
			String pbid = bid;
			Integer type = detailJO.getInteger("type");
			String vatNo = detailJO.getString("vatNo");
			String lastDateBegin = detailJO.getString("lastDateBegin");
			String lastDateEnd = detailJO.getString("lastDateEnd");
			String currentDateBegin = detailJO.getString("currentDateBegin");
			String currentDateEnd = detailJO.getString("currentDateEnd");
			String applyFile = detailJO.getString("applyFile");
			String remark = detailJO.getString("remark");
			String applyReply = detailJO.getString("applyReply");
			String currencyCode = detailJO.getString("currencyCode");
			BigDecimal taxAmount = detailJO.getBigDecimal("taxAmount");
			String vatPaymentAccountCode = detailJO.getString("vatPaymentAccountCode");
			Integer statePay = ThrVatApplyEnum.StatePay.NOT.value;
			ThrVatApplyDetail thrVatApplyDetail = ThrVatApplyDetail.thrVatApplyDetail(pbid, type, vatNo, lastDateBegin, lastDateEnd, currentDateBegin, currentDateEnd, applyFile, remark, applyReply, currencyCode, taxAmount, vatPaymentAccountCode, statePay, 1);
			thrVatApplyDetailMapper.insert(thrVatApplyDetail);
		}
		
		/*
		 * 流程初始化
		 */
		YsMenu ysMenu = new YsMenu().setId(menuId).queryFirst();
		if (ysMenu.getFlowModelId().longValue() != 0L) {
			YspModel yspModel = new YspModel().setId(ysMenu.getFlowModelId()).queryFirst();
			String codeModel = yspModel.getCode();
			String createUserId = ShiroUtils.getUserId();
			yspTaskService.init(codeModel, bid, createUserId);
		}
		return R.ok(AddDto.gotoEdit("/web/hr/thrVatApply/toFlow?bid=" + bid));
	}
	
	@Override
	@Transactional
	public R edit(String bid, String detailArr, Long menuId) throws Exception {
		
		Integer stateFlow = yspTaskService.flowState(bid);
		if (stateFlow == YsProcInstEnum.StateFlow.FINISH.value) {
			return R.error("已流转结束，无法修改");
		}
		
		/*
		 *  验证详情数据物料
		 *  1、VAT号不能为空
		 *  2、类型不能为空，类型为公司管理时，税额不能为空
		 *  3、申报周期不能为空
		 */
		JSONArray detailJA = JSON.parseArray(detailArr);
		if (detailJA == null || detailJA.size() == 0) {
			return R.error("详情数据不能为空");
		}
		String ids = "";
		for (int i = 0; i < detailJA.size(); i++) {
			JSONObject detailJO = detailJA.getJSONObject(i);
			String vatNo = detailJO.getString("vatNo");
			if (vatNo == null || vatNo.length() == 0) {
				return R.error("VAT号不能为空");
			}
			String currentDateBegin = detailJO.getString("currentDateBegin");
			if (currentDateBegin == null || currentDateBegin.length() == 0) {
				return R.error("申报周期(起始)不能为空");
			}
			String currentDateEnd = detailJO.getString("currentDateEnd");
			if (currentDateEnd == null || currentDateEnd.length() == 0) {
				return R.error("申报周期(截止)不能为空");
			}
			String vatPaymentAccountCode = detailJO.getString("vatPaymentAccountCode");
			if (vatPaymentAccountCode == null || vatPaymentAccountCode.length() == 0) {
				return R.error("VAT付款账户编码不能为空");
			}
			
			Integer type = detailJO.getInteger("type");
			if (type == null) {
				return R.error("类型不能为空");
			}
			if (type == ThrVatApplyDetailEnum.Type.COMPANY.value) {
				BigDecimal taxAmount = detailJO.getBigDecimal("taxAmount");
				if (taxAmount == null) {
					return R.error("税额不能为空");
				} else if (taxAmount.compareTo(BigDecimal.ZERO) < 0) {
					return R.error("税额必须为正");
				}
			}
			
			if (detailJO.containsKey("id")) {
				ids = ids + detailJO.getString("id") + ",";
			}
		}
		ids = ids.length() > 0 ? ids.substring(0, ids.length() - 1) : "";
		
		// 删除旧的详情数据
		if (stateFlow == YsProcInstEnum.StateFlow.INIT.value) {
			hrMapper.deleteBatchThrVatApplyDetailByBid(bid, ids);
		}
		
		// 添加或更新申请明细
		for (int i = 0; i < detailJA.size(); i++) {
			JSONObject detailJO = detailJA.getJSONObject(i);

			String pbid = bid;
			Integer type = detailJO.getInteger("type");
			String vatNo = detailJO.getString("vatNo");
			String lastDateBegin = detailJO.getString("lastDateBegin");
			String lastDateEnd = detailJO.getString("lastDateEnd");
			String currentDateBegin = detailJO.getString("currentDateBegin");
			String currentDateEnd = detailJO.getString("currentDateEnd");
			String applyFile = detailJO.getString("applyFile");
			String remark = detailJO.getString("remark");
			String applyReply = detailJO.getString("applyReply");
			String currencyCode = detailJO.getString("currencyCode");
			BigDecimal taxAmount = detailJO.getBigDecimal("taxAmount");
			String vatPaymentAccountCode = detailJO.getString("vatPaymentAccountCode");
			Integer statePay = ThrVatApplyEnum.StatePay.NOT.value;
			
			if (detailJO.containsKey("id")) {
				Long id = detailJO.getLong("id");
				ThrVatApplyDetail thrVatApplyDetail = new ThrVatApplyDetail().setId(id).queryFirst();
				thrVatApplyDetail
					.setVatNo(vatNo)
					.setCurrencyCode(currencyCode)
					.setVatPaymentAccountCode(vatPaymentAccountCode)
					.setTaxAmount(taxAmount);
				
				if (stateFlow == YsProcInstEnum.StateFlow.INIT.value) {
					thrVatApplyDetail
						.setLastDateBegin(lastDateBegin)
						.setLastDateEnd(lastDateEnd)
						.setCurrentDateBegin(currentDateBegin)
						.setCurrentDateEnd(currentDateEnd)
						.setApplyFile(applyFile)
						.setRemark(remark)
						.setApplyReply(applyReply)
						.setStatePay(statePay);
				}
				thrVatApplyDetailMapper.update(thrVatApplyDetail);
			} else {
				ThrVatApplyDetail thrVatApplyDetail = ThrVatApplyDetail.thrVatApplyDetail(pbid, type, vatNo, lastDateBegin, lastDateEnd, currentDateBegin, currentDateEnd, applyFile, remark, applyReply, currencyCode, taxAmount, vatPaymentAccountCode, statePay, 1);
				thrVatApplyDetailMapper.insert(thrVatApplyDetail);
			}
		}
		
		return R.ok(EditDto.reloadPage("/web/hr/thrVatApply/toFlow?bid=" + bid));
	}

	@Override
	@Transactional
	public R deleteTrue(Long id) throws Exception {
		if (id == null) {
			return R.error("ID不能为空");
		}
		
		ThrVatApply entity = new ThrVatApply().setId(id).queryFirst();
		if (entity.getEffectStock() == FlowEnum.EffectStock.EFFECTED.value) {
			return R.error("已生效数据无法删除");
		}
		// 验证是否制单人
		String loginUserId = ShiroUtils.getUserId();
		TsUserChange tsUserChange = new TsUserChange().setId(entity.getCreateChangeId()).queryFirst();
		
		if (!tsUserChange.getUserId().equals(loginUserId)) {
			return R.error("非制单人，无法删除");
		}
		
		// 删除主数据
		thrVatApplyMapper.deleteTrue(id);
		
		// 删除子数据
		List<ThrVatApplyDetail> listDetail = new ThrVatApplyDetail().setPbid(entity.getBid()).queryList();
		for(ThrVatApplyDetail detail : listDetail) {
			thrVatApplyDetailMapper.deleteTrue(detail.getId());
		}
		
		yspTaskService.flowDelete(entity.getBid(), loginUserId);
		return R.ok();
	}

	@Override
	@Transactional
	public R cancel(String bid) {
		if (bid == null || bid.length() == 0) {
			return R.error("ID不能为空");
		}
		
		ThrVatApply entity = new ThrVatApply().setBid(bid).queryFirst();
		if (entity.getEffectStock() != FlowEnum.EffectStock.EFFECTED.value) {
			return R.error("未生效数据无法作废");
		}
		
		// 作废主数据
		entity.setEffectStock(FlowEnum.EffectStock.CANCELD.value);
		thrVatApplyMapper.update(entity);

		List<ThrVatApplyDetail> thrVatApplyDetailList = new ThrVatApplyDetail().setPbid(entity.getBid()).queryList();
		for (ThrVatApplyDetail thrVatApplyDetail : thrVatApplyDetailList){
			List<ThrVatApplyDetailCbb> thrVatApplyDetailCbbList = new ThrVatApplyDetailCbb().setVatApplyDetailId(thrVatApplyDetail.getId()).queryList();
			for (ThrVatApplyDetailCbb thrVatApplyDetailCbb : thrVatApplyDetailCbbList){
				thrVatApplyDetailCbb.setStatus(0);
				thrVatApplyDetailCbbMapper.update(thrVatApplyDetailCbb);

				TccLogisticsSadFile tccLogisticsSadFile = new TccLogisticsSadFile().setId(thrVatApplyDetailCbb.getCbbId()).queryFirst();
				tccLogisticsSadFile.setDeclareState(0);
				tccLogisticsSadFile.setDeclareBid("");
				tccLogisticsSadFile.setDeclareTime(null);
				tccLogisticsSadFileMapper.update(tccLogisticsSadFile);
			}
		}
		return R.ok();
	}

	@Override
	@Transactional
	public R flowPass(String bid, String loginUserId) throws Exception {
		
		try {
			Flow f = yspTaskService.flowPass(bid, loginUserId);
			if (f.getCode() == Flow.Code.FAILED.value) {
				return R.error(f.getMsg());
			} else {
				
				if (f.getState() == Flow.State.FINISH.value) {
					flowFinish(bid);
				}
				return R.ok();
			}
		} catch (Exception e) {
			e.printStackTrace();
			return R.error("服务器正在开小差，请联系客服");
		}
	}

	@Override
	public R flowRefuse(String bid, String reason, String loginUserId) throws Exception {
		
		R r = yspTaskService.flowRefuse(bid, reason, loginUserId);
		return r;
	}

	@Override
	@Transactional
	public void flowFinish(String bid) throws Exception {

		ThrVatApply entity = new ThrVatApply().setBid(bid).queryFirst();
		
		YsProcInst ysProcInst = new YsProcInst().setBid(entity.getBid()).queryFirst();
		if (ysProcInst.getStateFlow() != YsProcInstEnum.StateFlow.FINISH.value) {
			return;
		}
		
		entity.setEffectStock(FlowEnum.EffectStock.EFFECTED.value);
		thrVatApplyMapper.update(entity);

		List<ThrVatApplyDetail> thrVatApplyDetailList = new ThrVatApplyDetail().setPbid(entity.getBid()).queryList();
		for (ThrVatApplyDetail thrVatApplyDetail : thrVatApplyDetailList){
			List<ThrVatApplyDetailCbb> thrVatApplyDetailCbbList = new ThrVatApplyDetailCbb().setVatApplyDetailId(thrVatApplyDetail.getId()).queryList();
			for (ThrVatApplyDetailCbb thrVatApplyDetailCbb : thrVatApplyDetailCbbList){
				TccLogisticsSadFile tccLogisticsSadFile = new TccLogisticsSadFile().setId(thrVatApplyDetailCbb.getCbbId()).queryFirst();
				tccLogisticsSadFile.setDeclareState(1);
				tccLogisticsSadFile.setDeclareBid(entity.getBid());
				tccLogisticsSadFile.setDeclareTime(new Date());
				tccLogisticsSadFileMapper.update(tccLogisticsSadFile);
			}
		}
		
//		List<ThrVatApplyDetail> listDetail = new ThrVatApplyDetail().setBidStockIn(bid).queryList();
//		for (int i = 0; i < listDetail.size(); i++) {
//			ThrVatApplyDetail detail = listDetail.get(i);
//			// 添加物料库存
//			TwlStock twlStock = null;
//			{
//				String companyVid = entity.getCompanyVid();
//				String orgid = entity.getOrgid();
//				String materialCode = detail.getMaterialCode();
//				Integer num = detail.getNum();
//				Integer numAll = detail.getNum();
//				Integer numFrozen = 0;
//				BigDecimal price = detail.getPrice();
//				String remark = detail.getRemark();
//				Long stockInDetailId = detail.getId();
//				String stockInDay = DateUtil.getYYMMDD(new Date());
//				twlStock = TwlStock.twlStock(companyVid, orgid, materialCode, num, numAll, numFrozen, price, stockInDetailId, stockInDay, remark, 1);
//				twlStockMapper.insert(twlStock);
//			}
//			
//			// 添加变动记录及流水记录
//			Long stockId = twlStock.getId();
//			Integer type = TwlStockChangeEnum.Type.IN.value;
//			Long sourceId = detail.getId();
//			String sourceBid = bid;
//			Integer sourceNum = detail.getNum();
//			twlStockService.change(stockId, type, sourceId, sourceBid, sourceNum);
//		}
	}


	//获取列表数据
	@Override
	@Transactional
	public Map<String,Object> getExtraParam(String bid) throws Exception{
		Map<String,Object> entity = new ThrVatApply().setBid(bid).queryFirstMap();
		return entity;
	}
	//获取子列表数据
	@Override
	@Transactional
	public List<Map<String, Object>> getItemList( String bid) throws Exception{
		// 子列表配置信息
		List<Map<String, Object>> sonlist = new ThrVatApplyDetail()
				.setPbid(bid)
				.addLeftJoin("THR_OperateCompanyEuropeTrade B1 on B1.VatNo = A.VatNo")
				.addLeftJoin("THR_OperateCompanyApply B2 on B2.Vgsbm = B1.Vgsbm")
				.addField("B2.Vgsbm vgsbm")
				.addField("B2.Vgsjc vgsjc")

				.addLeftJoin("TB_Country B3 on B3.Code = B1.CountryCode")
				.addField("B3.Code countryCode")
				.addField("B3.Name countryName")

				.addLeftJoin("TCW_VatPaymentAccount C ON C.Code = A.VatPaymentAccountCode")
				.addField("C.Vyhzhmc vatPaymentAccountVyhzhmc")
				.addField("C.Vkhh vatPaymentAccountVkhh")
				.addField("C.AchRouting vatPaymentAccountAchRouting")
				.addField("C.Vyhzh vatPaymentAccountVyhzh")
				.addField("C.SwiftCode vatPaymentAccountSwiftCode")

				.queryMap();
		return sonlist;
	}


}
